Skip to content

refactor: migrate all Xtend files to Java 21 - #1274

Draft
joaodinissf wants to merge 1 commit into
dsldevkit:masterfrom
joaodinissf:feature/xtend-to-java-migration
Draft

refactor: migrate all Xtend files to Java 21#1274
joaodinissf wants to merge 1 commit into
dsldevkit:masterfrom
joaodinissf:feature/xtend-to-java-migration

Conversation

@joaodinissf

@joaodinissf joaodinissf commented Mar 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Migrate all 88 Xtend (.xtend) source files to Java 21, leveraging modern language features (text blocks, enhanced switch, pattern matching, records). This eliminates the Xtend compilation step, significantly improving build times.

What's included

  • Xtend-to-Java migration of all .xtend files across check, checkcfg, export, expression, format, scope, and generator modules (Batches 1–9)
  • Xtend build infrastructure removal (maven-xtend-plugin, xtend-maven-plugin configs)
  • Code quality fixes: resolve all PMD, Checkstyle, and SpotBugs violations in migrated code
  • Modern Java idioms: replace StringBuilder patterns with String.format() and text blocks, convert string concatenation to text blocks in test DSL sources
  • Eclipse formatter applied to all migrated files
  • @SuppressWarnings("nls") added to suppress non-externalized string literal warnings

Build impact

Clean Eclipse build ~2.8x faster: from 14.44s down to 5.13s (measured on MacBook).

Test plan

  • CI maven-verify passes
  • CI PMD and Checkstyle checks pass
  • Manual verification in Eclipse IDE

🤖 Generated with Claude Code

@joaodinissf joaodinissf changed the title [CLAUDE] Xtend to Java migration [WIP] Xtend to Java migration Mar 1, 2026
* @return the model stub string
*/
public String modelWithGrammar() {
StringBuilder builder = new StringBuilder(512);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joaodinissf it is not using multi line strings...

@joaodinissf joaodinissf Mar 2, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I'll try to get it to clean this up later today.

@joaodinissf
joaodinissf marked this pull request as ready for review March 3, 2026 08:24
@joaodinissf joaodinissf changed the title [WIP] Xtend to Java migration refactor: migrate all Xtend files to Java 21 Mar 3, 2026
@joaodinissf
joaodinissf force-pushed the feature/xtend-to-java-migration branch 3 times, most recently from 84de93f to 76087e2 Compare March 3, 2026 18:38
@joaodinissf
joaodinissf marked this pull request as draft March 5, 2026 08:41
@joaodinissf
joaodinissf force-pushed the feature/xtend-to-java-migration branch 2 times, most recently from dee50e3 to 4163b68 Compare April 4, 2026 11:55
*
* Also see {@link org.eclipse.xtext.xtext.XtextFormatter} as an example
*/
public class «grammar.formatterStub.simpleName» extends «FormatGeneratorUtil::getFormatterName(grammar, "Abstract")» {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that for this kind of files were use use Xtend string interpolation, it actually makes sense to keep Xtend.

@joaodinissf
joaodinissf force-pushed the feature/xtend-to-java-migration branch 2 times, most recently from fddb296 to 5710dd2 Compare April 20, 2026 08:22
joaodinissf added a commit to joaodinissf/dsl-devkit that referenced this pull request May 20, 2026
Add a structured project skill encoding the Xtend → Java conversion
rules and methodology that previously lived only in the stale PR dsldevkit#1274
(`docs/xtend-to-java-conversion-prompt.md` and `docs/xtend-migration.md`).
The skill is split into a 1-line entry point, 10 rule files, 4 workflow
docs, 2 examples, and 1 reference table — Claude (or any LLM) can load
only the parts it needs.

Cross-tool generic location at `.agents/skills/` is the source of truth.
A POSIX shell script `.agents/sync.sh` mirrors it into `.claude/skills/`
(gitignored) for Claude Code's auto-discovery: symlink on macOS/Linux,
recursive copy on Windows where Git symlinks need Developer Mode.

After cloning, run `./.agents/sync.sh` once. Re-run after pulling
changes that touch `.agents/skills/`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@joaodinissf
joaodinissf force-pushed the feature/xtend-to-java-migration branch 6 times, most recently from 6d28382 to aef6caa Compare June 2, 2026 19:07
@joaodinissf
joaodinissf force-pushed the feature/xtend-to-java-migration branch 2 times, most recently from db22e58 to 85b6e59 Compare June 10, 2026 22:03
@rubenporras

Copy link
Copy Markdown
Member

Hi @joaodinissf ,

would you mind splitting out some parts of the PR so that we can look one by one?

I think for example, you could split already com.avaloq.tools.ddk.sample.helloworld.* and and com.avaloq.tools.ddk.checkcfg.* and com.avaloq.tools.ddk.xtext.ui.

I am working now on a big refactor of the scope, export and expression language to get rid of Xpand, so I am not sure it is worth to touch them, it would only give me headaches with merging.

b.append(getElementTypeName());
b.append("\")"); //$NON-NLS-1$
return b.toString();
return this.getClass().getSimpleName() + "(\"" + getElementTypeName() + "\")"; //$NON-NLS-1$ //$NON-NLS-2$

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is very unrelated. I would undo it.

StringBuilder stringBuilder = new StringBuilder(valueString.substring(0, MAX_FEATURE_VALUE_LENGTH - CONTINUED.length()));
stringBuilder.append(CONTINUED);
valueString = stringBuilder.toString();
valueString = valueString.substring(0, MAX_FEATURE_VALUE_LENGTH - CONTINUED.length()) + CONTINUED;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is very unrelated. I would undo it.

result.append('@');
result.append(Integer.toHexString(hashCode()));

String result = String.format("%s@%s", eObject.getClass().getName(), Integer.toHexString(hashCode())); //$NON-NLS-1$

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is very unrelated. I would undo it. Same for all the java files modifies in this plugin in this PR

joaodinissf added a commit to joaodinissf/dsl-devkit that referenced this pull request Jun 15, 2026
Consolidate the learnings from the per-module migration campaign into the skill
so future runs rely on the skill itself, not prompt-embedded notes:

- overview.md / one-file-conversion.md / SKILL.md: a fresh -T 3C build off the
  integration branch is the authoritative xtend-gen ground truth; the dsldevkit#1274
  reference is a (possibly stale) four-eyes cross-check, never a substitute.
- known-pitfalls.md: add constant-fields->static-final (FinalFieldCouldBeStatic),
  public @RegisterExtension, active-annotations-are-not-leaf-conversions,
  dsldevkit#1274-is-a-parity-not-compliance-oracle, method-count parity, empty-body-needs-
  comment, text-block-vs-inline-''' fidelity; correct the import-order entry;
  enrich IllegalCatch/IllegalThrows.
- validation-checklist.md: add gates 31-34.
- multi-file-batch.md: drop the commit-trailer rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
joaodinissf added a commit to joaodinissf/dsl-devkit that referenced this pull request Jun 15, 2026
Consolidate the learnings from the per-module migration campaign into the skill
so future runs rely on the skill itself, not prompt-embedded notes:

- overview.md / one-file-conversion.md / SKILL.md: a fresh -T 3C build off the
  integration branch is the authoritative xtend-gen ground truth; dsldevkit#1274 is a
  (possibly stale) four-eyes cross-check, never a substitute.
- known-pitfalls.md: constant-fields->static-final (FinalFieldCouldBeStatic),
  public @RegisterExtension, active-annotations-are-not-leaf-conversions,
  dsldevkit#1274-is-a-parity-not-compliance-oracle, method-count parity, empty-body-needs-
  comment, text-block-vs-inline-''' fidelity, and don't-carry-xbase.lib-Pair-into-
  migrated-Java (use a record; Map.entry rejects null); correct import-order;
  enrich IllegalCatch/IllegalThrows.
- infrastructure-cleanup.md: MANIFEST removal of xbase.lib/xtend.lib now requires
  grepping BOTH src and src-gen (remove iff zero refs; transitive availability is
  irrelevant at zero refs; Require-Bundle isn't re-exported).
- validation-checklist.md: add gates 31-34.
- multi-file-batch.md: drop the commit-trailer rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
joaodinissf added a commit to joaodinissf/dsl-devkit that referenced this pull request Jun 15, 2026
Consolidate the learnings from the per-module migration campaign into the skill
so future runs rely on the skill itself, not prompt-embedded notes:

- overview.md / one-file-conversion.md / SKILL.md: a fresh -T 3C build off the
  integration branch is the authoritative xtend-gen ground truth; dsldevkit#1274 is a
  (possibly stale) four-eyes cross-check, never a substitute.
- known-pitfalls.md: constant-fields->static-final (FinalFieldCouldBeStatic),
  public @RegisterExtension, active-annotations-are-not-leaf-conversions,
  dsldevkit#1274-is-a-parity-not-compliance-oracle, method-count parity, empty-body-needs-
  comment, text-block-vs-inline-''' fidelity, and don't-carry-xbase.lib-Pair-into-
  migrated-Java (use a record; Map.entry rejects null); correct import-order;
  enrich IllegalCatch/IllegalThrows.
- infrastructure-cleanup.md: MANIFEST removal of xbase.lib/xtend.lib now requires
  grepping BOTH src and src-gen (remove iff zero refs; transitive availability is
  irrelevant at zero refs; Require-Bundle isn't re-exported).
- validation-checklist.md: add gates 31-34.
- multi-file-batch.md: drop the commit-trailer rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
joaodinissf added a commit that referenced this pull request Jun 16, 2026
Consolidate the learnings from the per-module migration campaign into the skill
so future runs rely on the skill itself, not prompt-embedded notes:

- overview.md / one-file-conversion.md / SKILL.md: a fresh -T 3C build off the
  integration branch is the authoritative xtend-gen ground truth; #1274 is a
  (possibly stale) four-eyes cross-check, never a substitute.
- known-pitfalls.md: constant-fields->static-final (FinalFieldCouldBeStatic),
  public @RegisterExtension, active-annotations-are-not-leaf-conversions,
  #1274-is-a-parity-not-compliance-oracle, method-count parity, empty-body-needs-
  comment, text-block-vs-inline-''' fidelity, and don't-carry-xbase.lib-Pair-into-
  migrated-Java (use a record; Map.entry rejects null); correct import-order;
  enrich IllegalCatch/IllegalThrows.
- infrastructure-cleanup.md: MANIFEST removal of xbase.lib/xtend.lib now requires
  grepping BOTH src and src-gen (remove iff zero refs; transitive availability is
  irrelevant at zero refs; Require-Bundle isn't re-exported).
- validation-checklist.md: add gates 31-34.
- multi-file-batch.md: drop the commit-trailer rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
joaodinissf added a commit to joaodinissf/dsl-devkit that referenced this pull request Jun 17, 2026
…arlier)

Rebased the umbrella migration onto current upstream/master (40034eb). The 7 campaign-merged modules (dsldevkit#1416-dsldevkit#1422) and earlier-merged bundles (format.ide/ui, xtext.ui, generator.test, etc.) are reset to master so they drop from the diff. The umbrella now shows only the remaining-to-migrate modules: xtext.generator, check.core.test, xtext.export, check.core, xtext.format, xtext.expression, xtext.scope, xtext.check.generator, xtext.test.core (+ dsldevkit#1274's repo-wide Xtend-infra cleanup and migration docs). Note: export/generator carry dsldevkit#1274's migration of files master tweaked post-base (ExportGeneratorX dsldevkit#1425, CompareFragment2) — those modules are deferred/in-flight and will be re-migrated against current master.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@joaodinissf
joaodinissf force-pushed the feature/xtend-to-java-migration branch from 6c8b8cf to df84b85 Compare June 17, 2026 06:30
joaodinissf added a commit to joaodinissf/dsl-devkit that referenced this pull request Jun 25, 2026
…arlier)

Rebased the umbrella migration onto current upstream/master (40034eb). The 7 campaign-merged modules (dsldevkit#1416-dsldevkit#1422) and earlier-merged bundles (format.ide/ui, xtext.ui, generator.test, etc.) are reset to master so they drop from the diff. The umbrella now shows only the remaining-to-migrate modules: xtext.generator, check.core.test, xtext.export, check.core, xtext.format, xtext.expression, xtext.scope, xtext.check.generator, xtext.test.core (+ dsldevkit#1274's repo-wide Xtend-infra cleanup and migration docs). Note: export/generator carry dsldevkit#1274's migration of files master tweaked post-base (ExportGeneratorX dsldevkit#1425, CompareFragment2) — those modules are deferred/in-flight and will be re-migrated against current master.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@joaodinissf
joaodinissf force-pushed the feature/xtend-to-java-migration branch 2 times, most recently from b37889f to 917d931 Compare June 25, 2026 09:22
joaodinissf added a commit to joaodinissf/dsl-devkit that referenced this pull request Jul 19, 2026
…arlier)

Rebased the umbrella migration onto current upstream/master (40034eb). The 7 campaign-merged modules (dsldevkit#1416-dsldevkit#1422) and earlier-merged bundles (format.ide/ui, xtext.ui, generator.test, etc.) are reset to master so they drop from the diff. The umbrella now shows only the remaining-to-migrate modules: xtext.generator, check.core.test, xtext.export, check.core, xtext.format, xtext.expression, xtext.scope, xtext.check.generator, xtext.test.core (+ dsldevkit#1274's repo-wide Xtend-infra cleanup and migration docs). Note: export/generator carry dsldevkit#1274's migration of files master tweaked post-base (ExportGeneratorX dsldevkit#1425, CompareFragment2) — those modules are deferred/in-flight and will be re-migrated against current master.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@joaodinissf
joaodinissf force-pushed the feature/xtend-to-java-migration branch from 917d931 to 6753b0f Compare July 19, 2026 05:37
@rubenporras

Copy link
Copy Markdown
Member

@joaodinissf , also, now that export and scope are migrated, you are welcome as well to finish the migration from xtend to java, it should not conflict with any other ongoing work.

…ed work

This PR is the migration tracker: as per-module migrations land on master
through dedicated PRs, their counterparts here are dropped, shrinking this
PR until it is empty and can be closed.

Dropped in this rebase (master wins):
- com.avaloq.tools.ddk.check.core/**: migration fully landed on master
  (fd18e86..30ff3e0 polish series; no .xtend remains there)
- com.avaloq.tools.ddk.xtext.{export,expression,scope}/**: superseded by
  the dsldevkit#1405 Xbase rework (2973c5b); the conversions here predated it
- ddk-parent/pom.xml: global xtend-maven-plugin removal was premature
  (master still carries .xtend sources)

Kept (not yet landed via dedicated PRs): xtext.test.core Tag conversion
(pending dsldevkit#1423), .ide/.ui/generator Xtend build-infra cleanups, migration
docs and configuration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@joaodinissf
joaodinissf force-pushed the feature/xtend-to-java-migration branch from 6753b0f to 91ae694 Compare August 25, 2026 11:26
joaodinissf added a commit that referenced this pull request Aug 25, 2026
check.ide, check.ui, xtext.export.ide, xtext.expression.ide,
xtext.scope.ide, xtext.valid.ide and xtext.generator no longer contain
any Xtend sources, but still carried the xtend-gen source-folder entry
in .classpath, the xtend-gen reference in build.properties and the
tracked xtend-gen/.gitignore placeholder. Remove all three per module.

Extracted from the migration tracker PR #1274 (which sheds this part on
its next rebase). The tracker's accompanying .project linkedResources
deletions are deliberately not carried over.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants